package main

import (
	"bufio"
	"bytes"
	"crypto"
	"crypto/rsa"
	"crypto/x509"
	"encoding/base64"
	"encoding/pem"
	"fmt"
	"math/rand"
	"strings"
	"time"
)

var jetBrainsPrivateKey = `-----BEGIN RSA PRIVATE KEY-----
MIIEvQIBADANBgkqhkiG9w0BAQEFAASCBKcwggSjAgEAAoIBAQC8zN/3v/FJOYmWXm9NZ9C8kbfji3AC4m6gI6LtF4yneuCT3zPv8XbC083t9LnfMLEnhnkQMJATSaRbbrWhSDtdUrwE00EBc7DTBn9Fhm7VbCX0XRL9hEaHUtyjRCJ1ajtuPg+/BmGF0ecul/rcT3EcXwrMSiRCKjgaRnrUbtYBca1cBqG3iibG6XotwCJo26FaDbMXbkolemRGzYKcMt8QM9qVN8uIftDbmls1KLv92MKfliVJvztyUUF2v6Jz4FiyO97C9gl31wSfkSBoQ6bgWy4mU2wvqHTQW9C0PX23W3dAOmBpFaSQNi3+JArWMVnzyVrmpweZPxBHlQIb9GkDAgMBAAECggEALFiM9NLzWEk4/YZR62MKnvg1Mq/CUBMie9/S+ZCR+5a7oFAJkX7sb8ezM4TLkdaMjeWikwBtHvKptcYzyF3Af+OagSGjv7UOYArDIy/34Y5k/dhMyRpkPI3kgD7VPzIEIplWNn7HsliCzilphYztWwYh8akqihYDlnxehn5AKxdCltRX5euMEVoIEOP/Q/Hoo1tjlIxDfUEn68pGnLbCQRfTQrIxXW+BNd64BGGRtkyDLyTzD+o4yrj1FhsqU0sFdSt0e+kGJuRUG+bNaJvTgU7ZR7NtcwYLB83m2L8khtfhKaUzYbq3kldQ7bne+eDghsvq6MwF25wz+BVe1ZH0oQKBgQDishQK2fXI3KkDn8KmfLVtmygH8w2KpwUTPW2kTVUFgh+OwysPjM7rjrf9I7g5g36gBanBiWTKWwd8/KK3XssI/70efBb8UX8Uwa+5Iyh0yhujp0VVRUwfmhZqMMl1VPsAcKo5sZ+B65hn/dkA7NDlHI3w/f04vsLzM+Ne+uM04QKBgQDVNL77PgMGlQtY1ECm0k+eZnsvZXjNo0irWVBDK+2kEvixMNO/zlaSSJHg0qzI9bItQBvVLmZ0KyQFCP9Edo556QtVZUFAuNdK4616Z5oiMb++RjNY8F9omOYW0XMyWfA9+dtA74VY3Y+GZ+Mezbbtf+xmNpxxY29j18K3z1+2YwKBgEuYEnLj58AJRRr+RUx7PYzFNn4gIJ3hwCGAVHV7jCSAFcHndw6CZ+XI+7WgGaikHq+B8++jv0ZzQHX/UMtRAueHUCtAOfH9wyDKzaww+yam1ryl5Mrghtfq7BqRFjzYD7M/3qPKhWQviezzi09xqN8dvH9mUvB/PEcZQHLFuspBAoGABshvzwRxCjORsdjG2cfVGp/+CUr8Jeas+C6WPBzYqaCk4tY/1llVLcA7S+DH+HjAm2nvuL+KKOX6dmKL5Hy1GbHNV4EqK0n2J37I1R0YrT/R7tbC6XB0SJqcr1sohBCScRZS4GT+ZA5gc5E4i5FV4YZxWesg3Qah05ZYropdbCsCgYEA1PZfdnY0XfpkN+gIcVHPStFK+i0ZlADTohldNvR5WTYE6e0kD7ew10gB0lH7Z9FPzBna1QTW7vH8XNuK9YLL8/Aw9ijD2BV/hjizy3izEYjmYlkMpAEZvI66GOgyzD8ctna+rhUaTXkto01h32yd1MJAwtTTTRYQiQa+yqAcaI4=
-----END RSA PRIVATE KEY-----`
var jetBrainsCert = `-----BEGIN CERTIFICATE-----
MIIEdjCCAl6gAwIBAgIBDjANBgkqhkiG9w0BAQsFADAdMRswGQYDVQQDDBJMaWNlbnNlIFNlcnZlcnMgQ0EwHhcNMTgxMTAxMTIyMDQ2WhcNNDUwODA5MDIyNjA3WjAyMTAwLgYDVQQDDCdPREE0TUMweE9XODgtb2ZmbGluZS5sc3J2LmpldGJyYWlucy5jb20wggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQC8zN/3v/FJOYmWXm9NZ9C8kbfji3AC4m6gI6LtF4yneuCT3zPv8XbC083t9LnfMLEnhnkQMJATSaRbbrWhSDtdUrwE00EBc7DTBn9Fhm7VbCX0XRL9hEaHUtyjRCJ1ajtuPg+/BmGF0ecul/rcT3EcXwrMSiRCKjgaRnrUbtYBca1cBqG3iibG6XotwCJo26FaDbMXbkolemRGzYKcMt8QM9qVN8uIftDbmls1KLv92MKfliVJvztyUUF2v6Jz4FiyO97C9gl31wSfkSBoQ6bgWy4mU2wvqHTQW9C0PX23W3dAOmBpFaSQNi3+JArWMVnzyVrmpweZPxBHlQIb9GkDAgMBAAGjgaswgagwDgYDVR0PAQH/BAQDAgWgMB0GA1UdJQQWMBQGCCsGAQUFBwMBBggrBgEFBQcDAjAdBgNVHQ4EFgQUBBGJuMKK/onbJd3WGe2A8v/wM7YwTQYDVR0jBEYwRIAUpsRiEz+uvh6TsQqurtwXMd4J8VGhIaQfMB0xGzAZBgNVBAMMEkxpY2Vuc2UgU2VydmVycyBDQYIJAMCrW9HV+hjZMAkGA1UdEwQCMAAwDQYJKoZIhvcNAQELBQADggIBAEUOZqmt6sNSHVuUMlzh3lZIXliNYn9q+WUB9WQlStwAUoDRD5LwvdLCx7mAeThHEazjZp/nYdIAJFwbAPLI9486Q1BBzY5vKbhW8UtHRnh5jy7XJ6erFKCUa+fXLtVS39qyuQioht8SjO0jicPMSGzqyc6WhEExgVIWaZgmi+jbr4K/1pbhtaTjlp63phhgyrgmSK5POgj6+ksHSpCqeS1yD4NvL6K1r5+kE6k0ZyzufAJ4GAegcu5lW0QmxaCxwxJC1Fio86v6BQD9UGmvl6MOn9PAxgEfv6cNck1yJCm/uOX+C7gqHEsQRGFILIks+07WitrDsgW2U+JYbdUw99rbA3T+wQeepjFLhJHtOCIkLWiysJ0+QC9IbuRlxnyBT1byb9zxkSUz2/bYun88AllTfPqsNhboURMt0q/DuvNIfVE4MP5g3JZqo/jC+bI2uVT4t/MMvqYgeXaIusgP+74NO4nMsLqpdAoMvqivH3zh31HRcAN6Tc7ywIdz2+UAXMbwghH7LM0WCaJ2K4ge6UYxtkO9sqGhRk1BNuk8B/iYAxB63nxwLo/XbnDQGn6uh6Z1jFXHcfkzWOJ62i8JJyia10VZpNzDr2M/Bvj90Gf41wKQC2oWSbHcTdDMizfceq5KjM+/7I2NO6x6rRNQ7XLJIBhD76W6Y78R/SD4SiKm
-----END CERTIFICATE-----`

// 下面是针对这个 serverUid 的内容
// serverUid 填入字段 serverUid
var serverUid = "ODA4MC0xOW88-offline"

// leaseSignature 填入字段 serverLease
var leaseSignature = "SHA512withRSA-ocTPjF9QOqpYsFkc7L4cv2TGf8XomF/Vsx3bgfCPYme23c+a8fJyxXJgq1agSoxfqikBs+n9wUxjlPOj5Ot7LPacvqyRAXwaAaZ9j/16J/5yS5wxh7cgKAkrDcBT7bNOwNtV4TX6jCDkwoOazITaWbUFEjjRczbd+fyVrVVNpuTNEaElbB9pF6WGzpGWQADOUa9kGsGkmGagl6+Uf5Mp2ecxGG7s5scEtlOTvlkQ2yZ7D0/1OJtY2cd9eikZ+CEVjtXG0G2IpXUVXFjPUXPkrz4Gmtd0Oytz9x9BepjTA3YZcaQPbaQyNzQirKxU/zRin1qvruWS8vPwlgjnhMoIdA==-MIIEbDCCAlSgAwIBAgIBDjANBgkqhkiG9w0BAQsFADAYMRYwFAYDVQQDDA1KZXRQcm9maWxlIENBMB4XDTE4MTEwMTEyMjA0NloXDTQ1MDgwOTAyMjYwN1owMjEwMC4GA1UEAwwnT0RBNE1DMHhPVzg4LW9mZmxpbmUubHNydi5qZXRicmFpbnMuY29tMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAvMzf97/xSTmJll5vTWfQvJG344twAuJuoCOi7ReMp3rgk98z7/F2wtPN7fS53zCxJ4Z5EDCQE0mkW261oUg7XVK8BNNBAXOw0wZ/RYZu1Wwl9F0S/YRGh1Lco0QidWo7bj4PvwZhhdHnLpf63E9xHF8KzEokQio4GkZ61G7WAXGtXAaht4omxul6LcAiaNuhWg2zF25KJXpkRs2CnDLfEDPalTfLiH7Q25pbNSi7/djCn5YlSb87clFBdr+ic+BYsjvewvYJd9cEn5EgaEOm4FsuJlNsL6h00FvQtD19t1t3QDpgaRWkkDYt/iQK1jFZ88la5qcHmT8QR5UCG/RpAwIDAQABo4GmMIGjMA4GA1UdDwEB/wQEAwIFoDAdBgNVHSUEFjAUBggrBgEFBQcDAQYIKwYBBQUHAwIwHQYDVR0OBBYEFAQRibjCiv6J2yXd1hntgPL/8DO2MEgGA1UdIwRBMD+AFKOetkhnQhI2Qb1t4Lm0oFKLl/GzoRykGjAYMRYwFAYDVQQDDA1KZXRQcm9maWxlIENBggkA0myxg7KDeeEwCQYDVR0TBAIwADANBgkqhkiG9w0BAQsFAAOCAgEAPHH0BdV+tXrLgwBnuCm1s/hXojJf4RkkI8iUI9t8qwv6b9rbY1gq0BDRfbYPIu2X5IkKuTxbUkZ0lIabKvsMVojPmxUGRoSZkpuLg7OzlKnzuwE430K0I0sVqfyMvrMVFoANYC+XrU5m0rnSYdprz5Sw6mx8DOMG5+wYl3RCiYfSroEnHwLBrj5xQhQnsGwseS5K4eP4K5E7JuHJ7L2PyEm/32NFx5m1niwGX6e2ZzPqDVzu6QS0TYgIbIyFewfGHvJsaW03Gl8QOAbdzkrpu/kNu2jQCtKYS/MaaEce6skgahnvZUTCHdEmKgi0qlJmvNBCBpRKO0QphHNV3paKUf5MEFDCd0JLG3NTaQLjaS43NIlPQuJK9Jl4uKd7G/0uX4kIbErc4zLD4rwJbcxz6bA2ZtTfOTmi8loxvCO4ySlINjTwhIGGk0r5mfqcfDVYITdhZBOkY0HIZx2YtSy00i6YQTls3Cm3gslo7m3L4kDJ9YjWtvoXkwBHz1AJnLyHD+Nzxf0JwHOAwyMEJxB9NYG8Pl4aWUftxiTT0RLk5Au9bT784P+GqeroQ6pz69+lBEeMba0AZK/Blnz8lUQ1XBH4iCEzLXBUhvnCqWhLU7G+bhtglJ7cn4mq5gI1j7DXfw/WuGwvlk9aWQG5Kz5a0EnckzFr3bCMwLnlGfwyTt8="

// leaseContent 填入字段 leaseSignature
var leaseContent = "4102415999000:ODA4MC0xOW88-offline"

// getConfirmationStamp 生成确认码
func getConfirmationStamp(machineId string) string {
	// 获取毫秒时间戳
	time := time.Now().UnixNano() / 1e6
	// 要签名的内容是
	// time + ":" + machineId
	content := fmt.Sprintf("%d:%s", time, machineId)
	signature := signContent(content)
	return fmt.Sprintf("%d:%s:%s:%s:%s", time, machineId, "SHA1withRSA", signature, getPureCert(jetBrainsCert))
}

// getPureCert 获取只有编码内容的证书
func getPureCert(cert string) string {
	result := ""
	scanner := bufio.NewScanner(strings.NewReader(cert))
	for scanner.Scan() {
		// 所有用 -- 开头的都扔掉
		if strings.HasPrefix(scanner.Text(), "-----") {
			continue
		} else {
			result += scanner.Text()
		}
	}
	return result
}

// signContent 签名内容,这个内容任意
func signContent(content string) string {
	block, _ := pem.Decode([]byte(jetBrainsPrivateKey))
	private, err := x509.ParsePKCS8PrivateKey(block.Bytes)
	if err != nil {
		panic(err)
	}
	h := crypto.Hash.New(crypto.SHA1) //进行SHA1的散列
	h.Write([]byte(content))
	hashed := h.Sum(nil)
	signedData, err := rsa.SignPKCS1v15(nil, private.(*rsa.PrivateKey), crypto.SHA1, hashed)
	// Base64 编码来一个,好吗?
	encoded := base64.StdEncoding.EncodeToString(signedData)
	return encoded
}

var letterRunes = []rune("0123456789abcdefghijklmnopqrstuvwxyz")

func randStringRunes(n int) string {
	b := make([]rune, n)
	for i := range b {
		b[i] = letterRunes[rand.Intn(len(letterRunes))]
	}
	return string(b)
}

func getTicketId() string {
	return randStringRunes(10)
}

// buildResponse(licenseXML) 输入编码好的 XML
// 然后完成后处理和签名
func buildResponse(licenseXML []byte) string {
	// 后处理一下特殊字符
	licenseXML = bytes.Replace(licenseXML, []byte("&#x9;"), []byte("\t"), -1)
	// 现在可以对 XML 进行签名了
	response := fmt.Sprintf("<!-- %s-%s-%s -->\n%s",
		"SHA1withRSA",
		signContent(string(licenseXML)),
		getPureCert(jetBrainsCert),
		string(licenseXML))
	return response
}

// getProductType 获取产品类型,目前猜测 JB 插件开头是 P
func getProductType(productCode string) string {
	if strings.HasPrefix(productCode, "P") {
		return "plugin"
	} else {
		return "ide"

	}
}
